<script setup>
import { appStore } from '@/sotre/modules/app';
import { onLoad } from '@dcloudio/uni-app';
import { getCozeToken, getCozeAgentDetail, getCozeFile, chooseSystemFile } from '@/api/common';
import Markdown from '@/components/markdown/index.vue';
import System from '@/utils/system';
import AudioStreamPlayer from './utils/audioPlay.js';
import { useMessage } from 'wot-design-uni';
import Call from './call.vue';
import audioContext from './utils/audio';
import speech, { stopAudio, isAudioPlaying } from './utils/speech';
import translation from './utils/translation';
import { buildCozeWebSocketUrl, safeCloseWebSocket } from '@/utils/cozeWebSocket';
import LuchAudio from '@/components/audio/luch-audio.vue';
import { platform } from 'uview-plus';

const message = useMessage();
const { appInfo, userInfo } = toRefs(appStore());
const { uniPlatform } = toRefs(System.info);
const $post = inject('$post');
const $get = inject('$get');

console.log(System);

const token = ref(null);
const agentDetail = ref();
const chatList = ref([]);
const isRecord = ref(false);
const showKeyboard = ref(false);
const keyboardHeight = ref(0);
const isSound = ref(false);
const text = ref('');
const loading = ref(false);
const showUpload = ref(false);
const closeCode = ref(0);
const fileList = ref([]);
const showMore = ref(false);
const title = ref('');
const showCall = ref(false);
const record = ref(false);
const listen = ref(false);
const y = ref(0);
const show = ref(false);
const moveDistance = ref(0);
const shorts = ref([]);
const quote = ref('');

let cozeChat = {};
let destroy = false;
let ws = null;
let play = new AudioStreamPlayer();
let connect = false;
// 录音相关
let AudioContext = new audioContext();
let time = null;
let requestTask = null;

onLoad(opt => {
    if (opt && opt.id) {
        $get(`/platform/recordContent?id=${opt.id}`).then(res => {
            chatList.value = JSON.parse(res.data);
            cozeChat = appInfo.value;
            title.value = cozeChat.title;
            scrollToBottom();
        });
    }
    uni.showLoading({
        title: '资源加载中...',
        mask: true,
    });
    getToken();
    // #ifdef MP-WEIXIN
    uni.authorize({
        scope: 'scope.record',
        success() {
            console.log('录音权限已授权');
        },
        fail() {
            uni.showModal({
                title: '授权提示',
                content: '需要录音权限才能使用语音功能',
                showCancel: false,
                confirmText: '去设置',
                success: res => {
                    if (res.confirm) {
                        uni.openSetting({
                            success: settingRes => {
                                if (settingRes.authSetting['scope.record']) {
                                    console.log('录音权限已授权');
                                } else {
                                    console.log('录音权限未授权');
                                }
                            },
                            fail: () => {
                                console.log('录音权限未授权');
                            },
                        });
                    } else {
                        console.log('录音权限未授权');
                    }
                },
            });
        },
    });
    // #endif
});

onBeforeUnmount(() => {
    destroy = true;
    if (ws) {
        safeCloseWebSocket(ws);
        play.destroy();
        if (AudioContext.isRecording) {
            AudioContext.destroy();
        }
    }

    clearInterval(time);
    time = null;
    stopAudio();
});

watch(isSound, e => {
    if (!e) {
        play.stop();
    }
});

watch(listen, e => {
    if (e) {
        speech(token.value, chatList.value[chatList.value.length - 1].content);
        time = setInterval(() => {
            if (isAudioPlaying() === 2) {
                clearInterval(time);
                time = null;
                loading.value = false;
                listen.value = false;
            }
        }, 100);
    } else {
        stopAudio();
        clearInterval(time);
        time = null;
        loading.value = false;
    }
});

const getTitle = computed(() => {
    if (chatList.value.length > 0) {
        return title.value;
    } else {
        return agentDetail.value?.name;
    }
});

async function getToken() {
    let t = null;
    if (appInfo.value.enterprise) {
        t = uni.getStorageSync('PERSON_COZE_TOKEN');
    } else {
        t = uni.getStorageSync('COZE_TOKEN');
    }
    if (!t) {
        const res = await getCozeToken(appInfo.value.enterprise);
        token.value = res.token;
    } else {
        const time = new Date().getTime();
        if (time - t.time > 86399 * 1000) {
            const res = await getCozeToken(appInfo.value.enterprise);
            token.value = res.token;
        } else {
            token.value = t.token;
        }
    }

    agentDetail.value = await getCozeAgentDetail(appInfo.value.botId, token.value);
    connectFun();
    uni.hideLoading();
}

function connectFun() {
    const url = buildCozeWebSocketUrl(appInfo.value.botId, token.value);
    ws = uni.connectSocket({
        url,
        success: () => {
            console.log('WebSocket连接请求已发送');
        },
        fail: err => {
            console.error('WebSocket连接请求失败:', err);
        },
    });
    ws.onOpen(() => {
        console.log('连接成功');
        connect = true;
    });
    ws.onMessage(res => {
        const data = JSON.parse(res.data);

        if (data.event_type === 'chat.created') {
            const d = {
                id: new Date().getTime() + '',
                event_type: 'chat.update',
                data: {
                    input_audio: { format: 'pcm', codec: 'pcm', sample_rate: 48000 },
                    output_audio: {
                        codec: 'pcm',
                        pcm_config: { sample_rate: 24000, frame_size_ms: 300 },
                    },
                    turn_detection: {
                        type: 'server_vad',
                        silence_duration_ms: 1500,
                    },
                },
            };
            chatSend(d);
        } else if (data.event_type === 'conversation.chat.created') {
            if (!cozeChat.cozeConversationId) {
                cozeChat = {
                    title: title.value,
                    cozeConversationId: data.data.conversation_id,
                    content: JSON.stringify(chatList.value),
                    mode: 'coze',
                    botId: agentDetail.value.bot_id,
                    createTime: new Date().getTime(),
                    logo: agentDetail.value.icon_url,
                    name: agentDetail.value.name,
                    enterprise: appInfo.value.enterprise,
                };
                $post('/platform/addRecord', cozeChat).then(r => {
                    cozeChat.id = r.data;
                });
            }
            chatList.value.push({
                role: 'assistant',
                type: 'answer',
                content_type: 'text',
                content: '',
                reasoning_content: '',
                follow_up: [],
            });
            play.stop();
        } else if (
            data.event_type === 'conversation.message.delta' &&
            data.data.type === 'answer'
        ) {
            chatList.value[chatList.value.length - 1].content += data.data.content;
            // #ifdef H5 || MP-WEIXIN
            scrollToBottom();
            // #endif
        } else if (
            data.event_type === 'conversation.message.completed' &&
            data.data.type === 'answer'
        ) {
            loading.value = false;
            cozeChat.content = JSON.stringify(chatList.value);
            $post('/platform/updateRecord', cozeChat);
            // #ifdef APP-PLUS
            scrollToBottom();
            // #endif
        } else if (data.event_type === 'error') {
            loading.value = false;
            closeCode.value = data.data.code === 4101 ? 0 : data.data.code;
            if (data.data.code === 717990703) {
                chatList.value[chatList.value.length - 1].content +=
                    '扣子平台：我们当前正遇到服务器问题。请在短暂延迟后再次尝试您的请求。如果问题仍然存在，请稍后再试。';
                scrollToBottom();
                cozeChat.content = JSON.stringify(chatList.value);

                setTimeout(() => {
                    $post('/platform/updateRecord', cozeChat);
                }, 1000);
            } else if (data.data.code === 4101 && !destroy) {
                uni.showToast({
                    title: '该智能体暂无授权，请前往扣子平台检查',
                    icon: 'none',
                    duration: 3000,
                });
                setTimeout(() => {
                    uni.navigateBack();
                }, 3000);
            } else if (closeCode.value) {
                uni.showToast({
                    title: '扣子平台：您的账户余额不足，请充值',
                    icon: 'none',
                    duration: 3000,
                });
            }
        } else if (data.event_type === 'conversation.audio.delta' && data.data.type === 'answer') {
            if (isSound.value) {
                play.addAudio(data.data.content);
            }
        } else if (data.event_type === 'conversation.chat.canceled' && data.data.code === 2) {
            if (isSound.value) {
                play.stop();
            }
            if (chatList.value.length / 2 !== 0) {
                chatList.value[chatList.value.length - 1].content += '\n打断智能体对话';
            }
            loading.value = false;

            cozeChat.content = JSON.stringify(chatList.value);
            $post('/platform/updateRecord', cozeChat);
            if (requestTask) {
                requestTask.abort();
                requestTask = null;
            }
        } else if (data.event_type === 'conversation.chat.failed') {
            if (isSound.value) {
                play.stop();
            }

            if (chatList.value.length / 2 !== 0) {
                chatList.value[chatList.value.length - 1].content +=
                    '\n该智能体暂无法使用，请检查coze账户';
            }

            cozeChat.content = JSON.stringify(chatList.value);
            loading.value = false;

            setTimeout(() => {
                $post('/platform/updateRecord', cozeChat);
            }, 1000);
        }
    });
    ws.onClose(e => {
        connect = false;
        if (closeCode.value) {
            setTimeout(() => {
                uni.navigateBack();
            }, 3000);
        }
    });
    ws.onError(err => {
        console.log('WebSocket连接错误:', err);
        // #ifdef APP-PLUS
        if (JSON.stringify(err) === '{}') {
            setTimeout(() => {
                getToken();
            }, 1000);
            return;
        }
        // #endif
        // 检查是否是签名或认证错误
        if (err.errMsg && err.errMsg.includes('Invalid HTTP status')) {
            console.log('检测到签名验证错误，尝试重新获取token...');
            // 清除旧的token并重新获取
            if (appInfo.value.enterprise) {
                uni.removeStorageSync('PERSON_COZE_TOKEN');
            } else {
                uni.removeStorageSync('COZE_TOKEN');
            }
            // 重新获取token并连接
            setTimeout(() => {
                getToken();
            }, 1000);
        } else {
            uni.showToast({
                title: '链接错误，请稍后重试',
                icon: 'none',
                duration: 3000,
            });
        }
    });
}

function scrollToBottom() {
    if (uniPlatform.value === 'mp-weixin' || uniPlatform.value === 'app') {
        nextTick(() => {
            const el = uni.createSelectorQuery().select('.chat_list');
            el.boundingClientRect(data => {
                uni.pageScrollTo({
                    scrollTop: data.height,
                    duration: 300,
                });
            }).exec();
        });
    } else {
        // 在H5环境中，滚动整个页面到底部
        nextTick(() => {
            // 计算整个页面的高度
            const documentHeight = Math.max(
                document.body.scrollHeight,
                document.body.offsetHeight,
                document.documentElement.clientHeight,
                document.documentElement.scrollHeight,
                document.documentElement.offsetHeight
            );

            // 滚动到页面底部
            window.scrollTo({
                top: documentHeight,
                behavior: 'smooth',
            });
        });
    }
}

function chatSend(d) {
    showUpload.value = false;

    ws.send({
        data: JSON.stringify(d),
    });
}

function handleStop() {
    if (loading.value) {
        chatSend({
            id: new Date().getTime() + '',
            event_type: 'conversation.chat.cancel',
        });
    }
}

function focusFun(e) {
    if (e.detail.height > 100) {
        showUpload.value = false;
        keyboardHeight.value = e.detail.height;
    }
}

function blurFun() {
    keyboardHeight.value = 0;
    if (text.value.length === 0) {
        showKeyboard.value = false;
    }
}

function handleSubmit(item) {
    if (loading.value) {
        return uni.showToast({
            title: '请等待智能体回复',
            icon: 'none',
        });
    }
    let data = [];
    const content = { type: 'text', text: '' };
    if (item) {
        content.text = item;
    } else {
        content.text = text.value;
    }
    if (content.text.length === 0) {
        return uni.showToast({
            title: '请输入消息',
            icon: 'error',
        });
    }
    title.value = content.text.slice(0, 30);
    // 文件上传
    if (fileList.value.length > 0) {
        fileList.value.forEach(item => {
            let type = 'file';
            if (item.type.includes('image')) {
                type = 'image';
            } else if (item.type.includes('audio')) {
                type = 'audio';
            } else if (item.type.includes('video')) {
                type = 'video';
            }
            data.push({
                type: type,
                file_id: item.id,
                file_url: item.url,
            });
        });
    }
    fileList.value = [];
    if (quote.value) {
        content.refer_items = [{ type: 'text', text: '引用：' + quote.value }];
    }
    data.push(content);
    chatList.value.push({
        role: 'user',
        type: 'question',
        content_type: 'object_string',
        content: JSON.stringify(data),
    });
    const message = {
        id: new Date().getTime() + '',
        event_type: 'conversation.message.create',
        data: chatList.value[chatList.value.length - 1],
    };
    text.value = '';
    blurFun();
    quote.value = '';
    loading.value = true;
    scrollToBottom();
    chatSend(message);
}

function handleCopy(index) {
    uni.setClipboardData({
        data: chatList.value[index].content,
    });
    uni.showToast({
        title: '复制成功',
        icon: 'success',
    });
}

function handleReload(flag = false) {
    if (flag) {
        chatList.value.splice(chatList.value.length - 1, 1);
    }
    const message = {
        id: new Date().getTime() + '',
        event_type: 'conversation.message.create',
        data: chatList.value[chatList.value.length - 1],
    };
    quote.value = '';
    loading.value = true;
    chatSend(message);
}

function handleUpload(type) {
    if (loading.value) return;

    if (fileList.value.length >= 8) {
        return uni.showToast({
            title: '最多上传8个文件',
            icon: 'none',
        });
    }
    switch (type) {
        case 'camera':
            uni.chooseImage({
                count: 1,
                sizeType: ['original', 'compressed'],
                sourceType: ['camera'],
                success: async res => {
                    const r = await getCozeFile(res, token.value);
                    if (r) {
                        fileList.value.push({
                            type: 'image',
                            ...r,
                        });
                    }
                },
                fail: err => {
                    if (!err.errMsg.includes('cancel')) {
                        uni.showToast({
                            title: '请检查相机权限',
                            icon: 'none',
                            duration: 3000,
                        });
                    }
                },
            });
            break;
        case 'image':
            uni.chooseImage({
                count: 1,
                sourceType: ['album'], // 只允许从相册选择
                success: async res => {
                    const r = await getCozeFile(res, token.value);
                    if (r) {
                        let type = 'image';
                        if (res.tempFiles[0].type) {
                            if (res.tempFiles[0].type.includes('image')) {
                                type = 'image';
                            } else if (res.tempFiles[0].type.includes('audio')) {
                                type = 'audio';
                            } else {
                                type = 'file';
                            }
                        }
                        fileList.value.push({
                            type: type,
                            ...r,
                        });
                    }
                },
                fail: err => {
                    if (!err.errMsg.includes('cancel')) {
                        uni.showToast({
                            title: '请检查相册权限',
                            icon: 'none',
                            duration: 3000,
                        });
                    }
                },
            });
            break;
        case 'file':
            // #ifdef MP-WEIXIN
            uni.chooseMessageFile({
                count: 1,
                type: 'file',
                success: async res => {
                    const data = {
                        tempFilePaths: res.tempFiles.map(item => item.path),
                    };
                    const r = await getCozeFile(data, token.value);
                    if (r) {
                        let type = 'file';
                        if (res.tempFiles[0].type) {
                            if (res.tempFiles[0].type.includes('image')) {
                                type = 'image';
                            } else if (res.tempFiles[0].type.includes('audio')) {
                                type = 'audio';
                            } else if (res.tempFiles[0].type.includes('file')) {
                                const ext = res.tempFiles[0].path.split('.').pop();
                                if (
                                    ext === 'mp3' ||
                                    ext === 'wav' ||
                                    ext === 'm4a' ||
                                    ext === 'MP3' ||
                                    ext === 'WAV' ||
                                    ext === 'M4A'
                                ) {
                                    type = 'audio';
                                } else {
                                    type = 'file';
                                }
                            } else {
                                type = 'file';
                            }
                        }
                        fileList.value.push({
                            type: type,
                            ...r,
                        });
                    }
                },
            });
            // #endif
            // #ifdef H5
            uni.chooseFile({
                count: 1,
                type: 'file',
                success: async res => {
                    const r = await getCozeFile(res, token.value);
                    if (r) {
                        let type = 'file';
                        if (res.tempFiles[0].type) {
                            if (res.tempFiles[0].type.includes('image')) {
                                type = 'image';
                            } else if (res.tempFiles[0].type.includes('audio')) {
                                type = 'audio';
                            } else {
                                type = 'file';
                            }
                        }
                        fileList.value.push({
                            type: type,
                            ...r,
                        });
                    }
                },
            });
            // #endif
            // #ifdef APP-PLUS
            chooseSystemFile().then(async res => {
                console.log(res);
                const r = await getCozeFile(res, token.value);
                console.log(r);
                const image = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
                const audio = ['mp3', 'wav', 'ogg', 'aac'];
                let type = 'file';
                if (image.includes(res.name)) {
                    type = 'image';
                } else if (audio.includes(res.name)) {
                    type = 'audio';
                }
                console.log(type);
                if (r) {
                    fileList.value.push({
                        type: type,
                        ...r,
                    });
                }
            });
            // #endif
            break;
        default:
            break;
    }
}

function getFileType(str) {
    if (str.length <= 9) {
        // 如果字符串长度小于等于头4+尾5=9，直接返回原字符串
        return str;
    }
    const first4 = str.slice(0, 4); // 获取前4个字符
    const last5 = str.slice(-5); // 获取后5个字符
    return `${first4}***${last5}`; // 组合结果
}

function handleCreateNewChat() {
    if (loading.value) {
        return uni.showToast({
            title: '请等待智能体回复',
            icon: 'none',
        });
    }
    cozeChat = {};
    chatList.value = [];
}

function handleEditName() {
    if (!cozeChat.id) return;
    message
        .prompt({
            title: '对话名称',
            inputValue: title.value,
            inputPattern: /^(?!\s*$).+/,
        })
        .then(resp => {
            if (resp.action === 'confirm') {
                if (resp.value === title.value) return;
                $post('/platform/record/updateTitle', {
                    id: cozeChat.id,
                    title: resp.value,
                }).then(res => {
                    uni.showToast({
                        title: '修改成功',
                        icon: 'success',
                    });
                    title.value = resp.value;
                    cozeChat.title = resp.value;
                });
            }
        })
        .catch(error => {
            console.log(error);
        });
}

function handleDelete() {
    if (!cozeChat.id) return;
    uni.showModal({
        title: '删除对话',
        content: '确定删除该对话吗？',
        success: res => {
            if (res.confirm) {
                $post(`/platform/delRecord?id=${cozeChat.id}`).then(res => {
                    if (res.code === 200) {
                        uni.showToast({
                            title: '删除成功',
                            icon: 'success',
                        });
                        uni.navigateBack();
                    }
                });
            }
        },
    });
}

async function handleTouchStart(e) {
    moveDistance.value = 0;
    y.value = e.touches[0].clientY;
    record.value = true;
    // 确保录音开始
    if (!AudioContext.isRecording) {
        await AudioContext.startRecording();
    }
}

function handleTouchMove(e) {
    const currentY = e.touches[0].clientY;
    moveDistance.value = Math.max(0, y.value - currentY);
}

function handleTouchEnd(e) {
    // 确保record状态被正确设置
    if (record.value) {
        record.value = false;
        // 确保录音停止
        if (AudioContext && AudioContext.isRecording) {
            AudioContext.stopRecording(e => {
                if (moveDistance.value >= 80) return;
                uni.showLoading({
                    title: '语音识别中...',
                    mask: true,
                });
                translation(e).then(res => {
                    uni.hideLoading();
                    if (res && res.combinedPhrases && res.combinedPhrases[0].text) {
                        handleSubmit(res.combinedPhrases[0].text);
                    } else {
                        uni.showToast({
                            title: '暂未识别到语音',
                            icon: 'none',
                            duration: 3000,
                        });
                    }
                });
            });
        }
    }
}

function showCallFun() {
    showCall.value = true;
    play.stop();
}
function closeCall(e, data) {
    showCall.value = false;
    if (!connect) {
        connectFun();
    }

    if (data.length > 0) {
        if (!cozeChat.cozeConversationId) {
            cozeChat = {
                title: title.value,
                cozeConversationId: new Date().getTime(),
                content: JSON.stringify(chatList.value),
                mode: 'coze',
                botId: agentDetail.value.bot_id,
                createTime: new Date().getTime(),
                logo: agentDetail.value.icon_url,
                name: agentDetail.value.name,
                enterprise: appInfo.value.enterprise,
            };
            $post('/platform/addRecord', e).then(r => {
                cozeChat.id = r.data;
                chatList.value = chatList.value.concat(data);
            });
        } else {
            chatList.value = chatList.value.concat(data);
            cozeChat.content = JSON.stringify(chatList.value);
            $post('/platform/updateRecord', cozeChat);
        }
    }

    scrollToBottom();
}

function acceptCall() {
    ws.close();
}

function openShorts(i) {
    shorts.value = i;
    show.value = true;
}

function shortsUpload(i) {
    if (i.options.includes('image')) {
        uni.chooseImage({
            count: 1,
            sourceType: ['album', 'camera'],
            success: async res => {
                // #ifdef H5
                if (!res.tempFiles[0].type.includes('image'))
                    return uni.showToast({
                        title: '请选择图片',
                        icon: 'none',
                        duration: 3000,
                    });
                // #endif
                const r = await getCozeFile(res, token.value);
                if (r) {
                    i.value = r.url;
                    i.file_id = r.id;
                }
            },
            fail: err => {
                if (!err.errMsg.includes('cancel')) {
                    uni.showToast({
                        title: '请检查相册权限',
                        icon: 'none',
                        duration: 3000,
                    });
                }
            },
        });
    } else {
        // #ifdef APP-PLUS
        chooseSystemFile().then(async res => {
            const r = await getCozeFile(res, token.value);
            if (r) {
                i.value = r.url;
                i.file_id = r.id;
            }
        });
        // #endif
        // #ifdef H5
        uni.chooseFile({
            count: 1,
            type: 'file',
            success: async res => {
                const r = await getCozeFile(res, token.value);
                if (r) {
                    i.value = r.url;
                    i.file_id = r.id;
                }
            },
        });
        // #endif
        // #ifdef MP-WEIXIN
        uni.chooseMessageFile({
            count: 1,
            type: 'file',
            success: async res => {
                const data = {
                    tempFilePaths: res.tempFiles.map(item => item.path),
                };
                const r = await getCozeFile(data, token.value);
                if (r) {
                    i.value = r.url;
                    i.file_id = r.id;
                }
            },
        });
        // #endif
    }
}

function handelShorts() {
    const flag = shorts.value.components.every(i => i.value);
    if (!flag) {
        uni.showToast({
            title: '请确保快捷指令所有内容填写完整',
            icon: 'none',
            duration: 3000,
        });
        return;
    }
    if (loading.value)
        return uni.showToast({
            title: '请等待智能体回复',
            icon: 'none',
        });
    const commands = {
        command_id: shorts.value.id,
        parameters: shorts.value.components
            ? shorts.value.components
                  .map(item => {
                      if (item.type === 'file') {
                          return {
                              [`${item.name}`]: item.file_id,
                          };
                      }
                      return {
                          [`${item.name}`]: item.value,
                      };
                  })
                  .reduce((acc, curr) => {
                      return { ...acc, ...curr };
                  }, {})
            : null,
    };
    let content = { type: 'text' };
    content.text = shorts.value.name;
    let shortValue = [];
    shorts.value.components.forEach(item => {
        if (item.type === 'file') {
            shortValue.push({
                type: 'file',
                text: `${item.name}:<br/>${item.value.split('/').pop()}`,
                ext: item.options[0],
                url: item.value,
            });
        } else {
            shortValue.push({ type: 'text', text: `${item.name}:${item.value}` });
        }
    });
    content.shorts = shortValue;
    show.value = false;
    chatList.value.push({
        role: 'user',
        type: 'question',
        content_type: 'object_string',
        content: JSON.stringify([content]),
    });
    scrollToBottom();
    loading.value = true;
    if (!cozeChat.cozeConversationId) {
        cozeChat = {
            title: shorts.value.name,
            cozeConversationId: new Date().getTime(),
            content: JSON.stringify(chatList.value),
            mode: 'coze',
            botId: agentDetail.value.bot_id,
            createTime: new Date().getTime(),
            logo: agentDetail.value.icon_url,
            name: agentDetail.value.name,
            enterprise: appInfo.value.enterprise,
        };
        $post('/platform/addRecord', cozeChat).then(r => {
            cozeChat.id = r.data;
        });
    }
    chatList.value.push({
        role: 'assistant',
        type: 'answer',
        content_type: 'text',
        content: '',
        reasoning_content: '',
        follow_up: [],
    });
    const data = {
        bot_id: agentDetail.value.bot_id,
        user_id: userInfo.value.uid,
        stream: true,
        additional_messages: [chatList.value[chatList.value.length - 1]],
        shortcut_command: commands,
    };

    requestTask = uni.request({
        url: `${import.meta.env.VITE_COZE_URL}/v3/chat`,
        method: 'POST',
        data: data,
        timeout: 240000,
        header: {
            Authorization: `Bearer ${token.value}`,
        },
        success: res => {
            const strs = res.data.split('\n');

            let answer = [];
            strs.forEach((line, index, arr) => {
                if (
                    line.startsWith('data:') &&
                    arr[index - 1] === 'event:conversation.message.completed'
                ) {
                    try {
                        const r = JSON.parse(line.split('data:')[1]);
                        if (r.type === 'answer') {
                            answer.push(r);
                        }
                    } catch (e) {}
                }
            });
            answer.forEach(item => {
                chatList.value[chatList.value.length - 1].content += item.content;
            });
            if (answer.length === 0) {
                chatList.value[chatList.value.length - 1].content +=
                    '回复失败：请检查当前插件是否可用';
            }
            loading.value = false;
            cozeChat.content = JSON.stringify(chatList.value);
            scrollToBottom();
            $post('/platform/updateRecord', cozeChat);
        },
        fail: err => {
            if (err.errMsg === 'request:fail timeout') {
                chatList.value[chatList.value.length - 1].content += '回答超时，请重新发送';
                loading.value = false;
                cozeChat.content = JSON.stringify(chatList.value);
                scrollToBottom();
                $post('/platform/updateRecord', cozeChat);
            }
            console.log(err);
        },
    });
}

function handleRemove(index) {
    uni.showModal({
        title: '删除消息',
        content: '确定删除该消息吗？',
        success: res => {
            if (res.confirm) {
                chatList.value.splice(index, 1);
                cozeChat.content = JSON.stringify(chatList.value);
                $post('/platform/updateRecord', cozeChat);
            }
        },
    });
}
</script>

<template>
    <div class="chat" @click="showMore = false">
        <wd-popup
            v-model="show"
            position="bottom"
            closable
            :z-index="101"
            custom-style="border-radius:32rpx 32rpx 0 0"
        >
            <view class="shorts_box">
                <strong style="display: flex; align-items: center; gap: 10px">
                    <wd-img :src="shorts.icon_url" mode="widthFix" width="20px" height="20px" />
                    <text>{{ shorts.name }}</text>
                </strong>
                <div class="shorts_list">
                    <div
                        class="shorts_box_item"
                        v-for="(i, index) in shorts.components"
                        :key="index"
                    >
                        <template v-if="i.type === 'file'">
                            <div v-if="i.value" class="shorts_file" @click="shortsUpload(i)">
                                <u-icon
                                    :name="i.options.includes('image') ? 'photo' : 'file-text'"
                                    size="30"
                                ></u-icon>
                                <div class="shorts_file_name">
                                    <span>{{ i.value.split('/').pop() }}</span>
                                </div>
                                <wd-icon
                                    name="close-circle-filled"
                                    size="22px"
                                    @click.stop="i.value = ''"
                                ></wd-icon>
                            </div>
                            <div v-else class="shorts_box_item_name" @click="shortsUpload(i)">
                                <span>{{ i.name }}</span>
                                <div class="plus">
                                    <wd-icon name="add" size="16" color="#292a25"></wd-icon>
                                </div>
                            </div>
                        </template>
                        <template v-else-if="i.type === 'text'">
                            <div class="shorts_input">
                                <wd-input
                                    type="text"
                                    v-model="i.value"
                                    :placeholder="i.name"
                                    clearable
                                />
                            </div>
                        </template>
                        <template v-else-if="i.type === 'select'">
                            <wd-picker :columns="i.options" :label="i.name" v-model="i.value" />
                        </template>
                    </div>
                </div>
                <div class="shorts_btn" @click="handelShorts">
                    <wd-button type="warning">提交</wd-button>
                </div>
            </view>
        </wd-popup>
        <Call
            v-if="showCall"
            :agent="agentDetail"
            :token="token"
            @close="closeCall"
            @accept="acceptCall"
        ></Call>
        <wd-message-box></wd-message-box>
        <u-navbar :title="getTitle" autoBack placeholder></u-navbar>
        <div class="top" :style="{ top: System.customBarHeight + 'px' }">
            <div class="logo">
                <wd-img
                    :src="agentDetail?.icon_url"
                    width="40px"
                    height="40px"
                    round
                    mode="aspectFill"
                ></wd-img>
                <div class="name">{{ agentDetail?.name }}</div>
            </div>
            <div class="btns">
                <wd-icon
                    name="call"
                    size="22px"
                    v-if="platform !== 'weixin'"
                    @click="showCallFun"
                ></wd-icon>
                <u-icon
                    :name="isSound ? 'volume' : 'volume-off'"
                    size="22px"
                    @click="isSound = !isSound"
                    color="#000"
                ></u-icon>
                <view @click.stop.prevent="showMore = !showMore">
                    <wd-icon name="ellipsis" size="22px"></wd-icon>
                </view>
                <div class="more_btn" v-if="showMore">
                    <div class="more_btn_item" @click="handleCreateNewChat">
                        <wd-icon name="edit-outline" size="22px"></wd-icon>
                        <text>创建新对话</text>
                    </div>
                    <div class="more_btn_item" @click="handleEditName">
                        <wd-icon name="edit-1" size="22px"></wd-icon>
                        <text>编辑对话名称</text>
                    </div>
                    <div class="more_btn_item" style="color: red" @click="handleDelete">
                        <wd-icon name="delete-thin" size="22px"></wd-icon>
                        <text>从对话列表删除</text>
                    </div>
                </div>
            </div>
        </div>
        <div class="first" v-if="chatList.length === 0">
            <div class="center">
                <wd-img
                    :src="agentDetail?.icon_url"
                    width="100px"
                    height="100px"
                    round
                    mode="aspectFill"
                ></wd-img>
            </div>
            <div class="des">
                <div class="des-text">{{ agentDetail?.description || agentDetail?.name }}</div>
            </div>
            <div class="suggested_questions">
                <div
                    class="suggested_item"
                    v-for="item in agentDetail?.onboarding_info.suggested_questions"
                    :key="item"
                    @click="handleSubmit(item)"
                >
                    {{ item }}
                </div>
            </div>
        </div>
        <div v-else class="chat_box">
            <div class="chat_list">
                <template v-for="(item, index) in chatList" :key="index">
                    <div class="chat_item" :class="item.role">
                        <div
                            v-if="item.role === 'user'"
                            class="chat_item_content"
                            selectable="true"
                        >
                            <template
                                v-for="content in JSON.parse(item.content)"
                                :key="content.text"
                            >
                                <div class="chat_item_content_text">
                                    <template v-if="content.type === 'image'">
                                        <view style="padding-bottom: 10px">
                                            <wd-img
                                                :src="content.file_url"
                                                width="150px"
                                                mode="widthFix"
                                                enable-preview
                                            ></wd-img>
                                        </view>
                                    </template>
                                    <template v-else-if="content.type === 'audio'">
                                        <view style="width: 250px; padding: 10px 0">
                                            <LuchAudio
                                                :src="content.file_url"
                                                :name="content.file_url.split('/').pop()"
                                            ></LuchAudio>
                                        </view>
                                    </template>
                                    <template v-else-if="content.type === 'text'">
                                        <div
                                            class="quote_text"
                                            v-for="i in content.refer_items"
                                            :key="i.text"
                                        >
                                            <text>{{ i.text }}</text>
                                        </div>
                                        <div class="shorts-user">
                                            <template v-for="i in content.shorts" :key="i.file_id">
                                                <div
                                                    v-if="i.type === 'text'"
                                                    class="w-fit"
                                                    style="background: #f9712e"
                                                >
                                                    <text
                                                        selectable="true"
                                                        user-select="text"
                                                        class="text-body2"
                                                    >
                                                        ✨{{ i.text }}
                                                    </text>
                                                </div>
                                                <div
                                                    v-else-if="i.ext === 'image'"
                                                    class="w-fit"
                                                    style="padding: 0px"
                                                >
                                                    <wd-img
                                                        :src="i.url"
                                                        width="120px"
                                                        mode="widthFix"
                                                        enable-preview
                                                    ></wd-img>
                                                </div>
                                                <div v-else class="w-fit">
                                                    <text
                                                        selectable="true"
                                                        user-select="text"
                                                        class="text-body2"
                                                    >
                                                        {{ i.text }}
                                                    </text>
                                                </div>
                                            </template>
                                        </div>
                                        <div class="chat_item_content_text_item">
                                            <text selectable="true" user-select="text">
                                                {{ content.text }}
                                            </text>
                                        </div>
                                    </template>
                                    <template v-else>
                                        <div class="file">
                                            <u-icon name="file-text" size="30"></u-icon>
                                            <div class="file_text">
                                                <a
                                                    :href="content.file_url"
                                                    target="_blank"
                                                    rel="noopener noreferrer"
                                                    style="flex: 1"
                                                >
                                                    {{ content.file_url.split('/').pop() }}
                                                </a>
                                            </div>
                                        </div>
                                    </template>
                                    <div
                                        v-if="index === chatList.length - 1 && !loading"
                                        class="user-btns"
                                    >
                                        <wd-img
                                            src="/static/chat/reload.png"
                                            width="30px"
                                            height="30px"
                                            mode="widthFix"
                                            @click="handleReload(false)"
                                        ></wd-img>
                                        <div class="deltet" @click="handleRemove(index)">
                                            <wd-img
                                                src="/static/chat/delete.png"
                                                width="18px"
                                                height="18px"
                                                mode="widthFix"
                                            ></wd-img>
                                        </div>
                                    </div>
                                </div>
                            </template>
                        </div>
                        <template v-else>
                            <div class="column">
                                <!-- 正文渲染 -->
                                <div
                                    style="display: flex; flex-direction: column"
                                    v-if="item.content"
                                >
                                    <Markdown
                                        v-if="
                                            item.role === 'assistant' &&
                                            item.content_type === 'text' &&
                                            item.content
                                        "
                                        :source="item.content"
                                        style="width: 100%"
                                    />
                                    <!-- 小组件 -->
                                    <div
                                        v-if="index === chatList.length - 1 && !loading"
                                        class="components"
                                    >
                                        <wd-img
                                            src="/static/chat/copy.png"
                                            width="30px"
                                            height="30px"
                                            mode="widthFix"
                                            @click="handleCopy(chatList.length - 1)"
                                        ></wd-img>
                                        <wd-img
                                            src="/static/chat/quote.png"
                                            width="30px"
                                            height="30px"
                                            mode="widthFix"
                                            @click="quote = item.content"
                                        ></wd-img>
                                        <template v-if="uniPlatform === 'mp-weixin'">
                                            <wd-img
                                                v-if="!listen"
                                                src="/static/chat/listen.png"
                                                width="30px"
                                                height="30px"
                                                mode="widthFix"
                                                @click="listen = true"
                                            ></wd-img>
                                            <wd-icon
                                                v-else
                                                name="stop-circle"
                                                size="22px"
                                                @click="listen = false"
                                            ></wd-icon>
                                        </template>
                                        <wd-img
                                            src="/static/chat/reload.png"
                                            width="30px"
                                            height="30px"
                                            mode="widthFix"
                                            @click="handleReload(true)"
                                        ></wd-img>
                                        <div class="deltet" @click="handleRemove(index)">
                                            <wd-img
                                                src="/static/chat/delete.png"
                                                width="18px"
                                                height="18px"
                                                mode="widthFix"
                                            ></wd-img>
                                        </div>
                                    </div>
                                </div>
                                <div
                                    class="dots-container"
                                    v-if="loading && index === chatList.length - 1"
                                >
                                    <div class="dot"></div>
                                    <div class="dot"></div>
                                    <div class="dot"></div>
                                    <div class="dot"></div>
                                    <div class="dot"></div>
                                </div>
                            </div>
                        </template>
                    </div>
                </template>
            </div>
        </div>
        <div class="form_box" :style="{ bottom: showUpload ? '110px' : keyboardHeight + 'px' }">
            <div class="shorts" v-if="!record && agentDetail?.shortcut_commands.length > 0">
                <div
                    class="shorts_item"
                    v-for="(i, index) in agentDetail?.shortcut_commands"
                    :key="index"
                    @click="openShorts(i)"
                >
                    {{ i.name }}
                </div>
            </div>
            <div class="form_content">
                <div class="file_list" v-if="fileList.length > 0">
                    <div class="file_item" v-for="(item, index) in fileList" :key="item.id">
                        <wd-img
                            v-if="item.type === 'image'"
                            :src="item.url"
                            width="100%"
                            mode="widthFix"
                        ></wd-img>
                        <div class="file_name" v-else>
                            <u-icon name="file-text" size="30px" color="#000"></u-icon>
                            <div class="file_name_text">
                                {{ getFileType(item.url.split('/').pop()) }}
                            </div>
                        </div>
                        <div class="close" @click="fileList.splice(index, 1)">
                            <wd-icon name="close-normal" size="18px" color="#fff"></wd-icon>
                        </div>
                    </div>
                </div>
                <div class="quote" v-if="quote">
                    <div class="quote_content">
                        {{ quote }}
                    </div>
                    <wd-icon
                        name="close-circle"
                        size="18px"
                        color="red"
                        @click="quote = ''"
                    ></wd-icon>
                </div>
                <div class="form" v-if="showKeyboard">
                    <textarea
                        v-model="text"
                        placeholder="请输入消息"
                        :adjustPosition="false"
                        disableDefaultPadding
                        autoHeight
                        :maxlength="999999999999"
                        focus
                        :show-confirm-bar="false"
                        confirm-type="send"
                        @focus="focusFun"
                        @blur="blurFun"
                        @confirm="handleSubmit(null)"
                    ></textarea>
                </div>
                <div class="default">
                    <wd-icon name="camera" size="23px" @click="handleUpload('camera')"></wd-icon>
                    <div v-if="showKeyboard" class="text"></div>
                    <template v-else>
                        <div v-if="!isRecord" class="text" @click="showKeyboard = true">
                            发送消息
                        </div>
                        <view
                            v-else
                            class="text"
                            @touchstart="handleTouchStart"
                            @touchend="handleTouchEnd"
                            @touchmove="handleTouchMove"
                        >
                            <div :style="{ display: record ? 'flex' : 'none' }" class="record_btn">
                                <image src="/static/chat/record.svg" alt="" />
                                <span>松开结束</span>
                                <image src="/static/chat/record.svg" alt="" />
                                <div class="close_record">
                                    <span>取消发送</span>
                                    <wd-icon name="close-circle" size="18px"></wd-icon>
                                </div>
                            </div>
                            <div :style="{ display: record ? 'none' : 'block' }">按住说话</div>
                        </view>
                    </template>
                    <div class="right" v-if="!showKeyboard">
                        <wd-icon
                            :name="isRecord ? 'keywords' : 'sound'"
                            size="24px"
                            @click="isRecord = !isRecord"
                        ></wd-icon>
                        <view v-if="loading" @click.stop="handleStop">
                            <wd-loading size="25px" type="outline">
                                <wd-icon name="stop-circle" size="22px"></wd-icon>
                            </wd-loading>
                        </view>
                        <u-icon
                            v-else
                            :name="showUpload ? 'close-circle' : 'plus-circle'"
                            size="26px"
                            color="#000"
                            @click="showUpload = !showUpload"
                        ></u-icon>
                    </div>
                    <div class="right" v-else>
                        <u-icon
                            :name="showUpload ? 'close-circle' : 'plus-circle'"
                            size="26px"
                            color="#000"
                            @click="showUpload = !showUpload"
                        ></u-icon>
                        <view v-if="loading" @click.stop="handleStop">
                            <wd-loading size="25px" type="outline">
                                <wd-icon name="stop-circle" size="22px"></wd-icon>
                            </wd-loading>
                        </view>
                        <div
                            v-else
                            class="send"
                            :class="{ send_active: text.length > 0 }"
                            @click="handleSubmit(null)"
                        >
                            <wd-img
                                src="/static/chat/send.png"
                                width="20px"
                                height="20px"
                                mode="widthFix"
                            ></wd-img>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="tools" :style="{ bottom: showUpload ? '0px' : '-130px' }">
            <div class="tool_item" @click="handleUpload('camera')">
                <wd-img
                    src="/static/chat/camera.png"
                    width="25px"
                    height="25px"
                    mode="widthFix"
                ></wd-img>
                <span>拍照</span>
            </div>
            <div class="tool_item" @click="handleUpload('image')">
                <wd-img
                    src="/static/chat/phone.png"
                    width="25px"
                    height="25px"
                    mode="widthFix"
                ></wd-img>
                <span>图片</span>
            </div>
            <!-- #ifdef MP-WEIXIN -->
            <div class="tool_item" @click="handleUpload('file')">
                <wd-img
                    src="/static/chat/wechat.png"
                    width="25px"
                    height="25px"
                    mode="widthFix"
                ></wd-img>
                <span>微信文件</span>
            </div>
            <!-- #endif -->
            <!-- #ifdef H5 || APP-PLUS-->
            <div class="tool_item" @click="handleUpload('file')">
                <wd-img
                    src="/static/chat/file.png"
                    width="25px"
                    height="25px"
                    mode="widthFix"
                ></wd-img>
                <span>文件</span>
            </div>
            <!-- #endif -->
        </div>
    </div>
</template>

<style lang="scss" scoped>
.chat {
    :deep(.u-navbar__content__title) {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .shorts_box {
        padding: 15px;
        background: #fff;
        border-radius: 10px;
        min-height: 300px;
        display: flex;
        align-items: center;
        flex-direction: column;
        position: relative;
        border-radius: 32rpx 32rpx 0 0;
        .shorts_btn {
            position: absolute;
            bottom: 10px;
            left: 50%;
            width: calc(100% - 30px);
            transform: translateX(-50%);
            padding: 10px 15px;
            display: flex;
            justify-content: center;
            align-items: center;
            :deep(.wd-button) {
                width: 80%;
            }
        }
        .shorts_list {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: 10px;
            padding: 20px 15px 50px 15px;
            width: calc(100% - 30px);
            .shorts_box_item {
                display: flex;
                align-items: center;
                gap: 10px;
                padding: 0 15px;
                :deep(.wd-picker) {
                    width: 100%;
                }
                .shorts_file {
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    gap: 10px;
                    border-bottom: 1px solid #d4d4d4;
                    width: 100%;
                    .shorts_file_name {
                        flex: 1;
                        overflow: hidden;
                        text-overflow: ellipsis;
                        white-space: nowrap;
                        width: 200px;
                        font-size: 14px;
                    }
                }
                .shorts_input {
                    width: 100%;
                }
                .shorts_box_item_name {
                    display: flex;
                    align-items: center;
                    gap: 10px;
                    justify-content: space-between;
                    width: 100%;
                    padding: 5px 10px;
                    border: 1px solid #d4d4d4;
                    border-radius: 10px;
                    .plus {
                        width: 20px;
                        height: 20px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        border-radius: 3px;
                        border: 1px solid #292a25;
                    }
                }
            }
        }
    }
    .tools {
        position: fixed;
        left: 0;
        width: calc(100% - 30px);
        border-radius: 12px 12px 0 0;
        padding: 0 15px 15px 15px;
        display: flex;
        align-items: center;
        gap: 15px;
        height: 100px;
        transition: all 0.3s ease;
        background: #fff;
        z-index: 10;
        .tool_item {
            flex: 1;
            aspect-ratio: 4/3;
            display: flex;
            align-items: center;
            justify-content: center;
            background: #f5f5f5;
            border-radius: 15px;
            flex-direction: column;
            gap: 5px;
            font-size: 12px;
        }
    }
    .top {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 5px 15px;
        background: #fff;
        position: fixed;
        left: 0;
        width: calc(100% - 30px);
        z-index: 9;

        .logo {
            display: flex;
            align-items: center;
            gap: 10px;
            .name {
                font-weight: bold;
                max-width: 200px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
        }
        .btns {
            display: flex;
            align-items: center;
            gap: 12px;
            .more_btn {
                position: absolute;
                min-width: fit-content;
                right: 15px;
                top: 50px;
                background: #fff;
                padding: 15px;
                border-radius: 10px;
                box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.15);
                display: flex;
                align-items: center;
                flex-direction: column;
                gap: 12px;
                .more_btn_item {
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    width: 100%;
                    justify-content: flex-start;
                    text {
                        min-width: fit-content;
                    }
                }
            }
        }
    }
    .chat_box {
        .chat_list {
            display: flex;
            align-items: center;
            flex-direction: column;
            gap: 10px;
            padding: 65px 15px 160px 15px;
            .chat_item {
                width: 100%;
                display: flex;
                .chat_item_content {
                    width: fit-content;
                    padding: 10px;
                    border-radius: 10px;
                    word-break: break-all;
                }
            }
            .assistant {
                align-items: flex-start;
                .column {
                    width: fit-content;
                    background: #f5f5f5;
                    padding: 10px;
                    border-radius: 10px;
                    max-width: calc(100% - 20px);
                    .components {
                        display: flex;
                        align-items: center;
                        gap: 12px;
                        margin-top: 10px;
                        .deltet {
                            width: 30px;
                            height: 30px;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            border-radius: 10px;
                            background: #f7ede6;
                        }
                    }
                }
            }

            .user {
                flex-direction: row-reverse;
                align-items: flex-end;
                .user-btns {
                    display: flex;
                    align-items: center;
                    gap: 10px;
                    margin-top: 10px;
                    .deltet {
                        width: 30px;
                        height: 30px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        border-radius: 10px;
                        background: #f7ede6;
                    }
                }
                .chat_item_content {
                    max-width: calc(100% - 20px);
                    .chat_item_content_text {
                        display: flex;
                        flex-direction: column;
                        align-items: flex-end;
                    }
                    .quote_text {
                        background: #e0e0e0;
                        padding: 3px 5px;
                        border-radius: 5px;
                        margin-bottom: 5px;
                        font-size: 12px;
                        color: #333;
                        display: -webkit-box;
                        -webkit-line-clamp: 2; /* 限制显示的行数 */
                        -webkit-box-orient: vertical;
                        overflow: hidden;
                        text-overflow: ellipsis;
                    }
                    .shorts-user {
                        display: flex;
                        flex-direction: column;
                        align-items: flex-end;
                    }
                    .w-fit {
                        color: #fff;
                        padding: 10px;
                        line-height: 1.2;
                        border-radius: 10px;
                        width: fit-content;
                        margin-bottom: 10px;
                        font-size: 14px;
                        display: flex;
                        align-items: center;
                        gap: 5px;
                        user-select: text;
                        -webkit-user-select: text;
                        .text-body2 {
                            text-align: justify;
                        }
                    }
                    .chat_item_content_text_item {
                        background: #f9712e;
                        color: #fff;
                        padding: 10px;
                        line-height: 1.2;
                        border-radius: 10px;
                        width: fit-content;
                        user-select: text;
                        -webkit-user-select: text;
                    }
                    .file {
                        display: flex;
                        align-items: center;
                        gap: 5px;
                        padding: 10px;
                        background: #f5f5f5;
                        border-radius: 10px;
                        margin: 10px 0;
                        font-size: 12px;
                        .file_text {
                            color: #4e80ec;
                            text-decoration: underline;
                        }
                    }
                }
            }
        }
    }
    .form_box {
        position: fixed;
        left: 0px;
        width: 100%;
        background: #fff;
        padding: 10px 0 25px 0;
        isolation: isolate;
        transition: all 0.3s ease;
        border-top: 1px solid #f5f5f5;
        z-index: 100;
        .shorts {
            position: absolute;
            top: -53px;
            padding: 10px 15px;
            width: calc(100% - 30px);
            z-index: 10;
            overflow-x: auto;
            display: flex;
            align-items: center;
            gap: 10px;
            background: linear-gradient(to bottom, transparent, #fff 50%);
            border-bottom: 1px solid #f5f5f5;
            &::-webkit-scrollbar {
                display: none;
            }
            .shorts_item {
                padding: 6px 10px;
                border-radius: 10px;
                background: #f5f5f5;
                font-size: 14px;
                flex: none;
                width: fit-content !important;
                border: 1px solid #919191;
            }
        }
        .form_content {
            padding: 12px 15px;
            background: #fff;
            border-radius: 12px;
            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.12);
            border: 1px solid #a8a8a8;
            z-index: 10;
            margin: 0 15px;
            .quote {
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 5px 10px;
                background: #cde7ed;
                border-radius: 7px;
                margin-bottom: 10px;
                font-size: 12px;
                .quote_content {
                    flex: 1;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }
            }
        }

        .file_list {
            display: flex;
            align-items: center;
            gap: 12px;
            flex-wrap: wrap;
            padding-bottom: 10px;
            .file_item {
                width: 20%;
                aspect-ratio: 1/1;
                border-radius: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 2px;
                position: relative;
                border: 1px solid #e5e5e5;
                .close {
                    position: absolute;
                    width: 20px;
                    height: 20px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border-radius: 50%;
                    background: red;
                    right: -5px;
                    top: -5px;
                }
                .file_name {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    flex-direction: column;
                    gap: 10px;
                    text-align: center;
                    font-size: 12px;
                    width: 100%;
                    min-width: 0;
                    .file_name_text {
                        width: 100%;
                        overflow: hidden;
                        text-overflow: ellipsis;
                        white-space: nowrap;
                        min-width: 0;
                    }
                }
            }
        }

        .default {
            display: flex;
            align-items: center;
            gap: 12px;
            .text {
                flex: 1;
                text-align: center;
                color: #2c2c2c;
                font-weight: bold;
            }
            .record_btn {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 3px;
                font-size: 10px;
                color: #2c2c2c;
                position: relative;
                user-select: none;
                .close_record {
                    position: absolute;
                    left: 50%;
                    transform: translateX(-40%);
                    top: -100px;
                    height: 36px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 50%;
                    border-radius: 50px;
                    background: #e9e9e9;
                    gap: 10px;
                    z-index: 10;
                    &:hover {
                        background: #bdbdbd;
                    }
                    &:active {
                        background: #bdbdbd;
                    }
                }
                image {
                    width: 30px;
                    height: 20px;
                }
            }
            .right {
                display: flex;
                align-items: center;
                gap: 10px;
                .send {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 27px;
                    height: 27px;
                    border-radius: 50%;
                    background: rgba(62, 90, 248, 0.5);
                }
                .send_active {
                    background: #4e80ec;
                }
            }
        }
        :deep(.form) {
            textarea {
                width: 100%;
                padding-bottom: 10px;
            }
        }
    }
    .first {
        margin: 15px;
        padding-top: 60px;
        .center {
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .des {
            padding: 10px;
            background: #f5f5f5;
            border-radius: 10px;
            margin: 12px 0;

            .des-text {
                overflow: hidden;
                text-overflow: ellipsis;
                display: -webkit-box;
                -webkit-line-clamp: 10;
                -webkit-box-orient: vertical;
                text-align: justify;
            }
        }
        .suggested_questions {
            display: flex;
            flex-direction: column;
            gap: 12px;
            .suggested_item {
                padding: 8px 10px;
                border-radius: 10px;
                width: fit-content;
                border: 1px solid #e5e5e5;
                font-size: 14px;
            }
        }
    }
}
</style>

<style>
/* From Uiverse.io by adamgiebl */
.dots-container {
    display: flex;
    align-items: center;
    height: 100%;
    width: 100%;
    padding: 10px;
}

.dot {
    height: 10px;
    width: 10px;
    margin-right: 10px;
    border-radius: 10px;
    background-color: #b3d4fc;
    animation: pulse 1.5s infinite ease-in-out;
}

.dot:last-child {
    margin-right: 0;
}

.dot:nth-child(1) {
    animation-delay: -0.3s;
}

.dot:nth-child(2) {
    animation-delay: -0.1s;
}

.dot:nth-child(3) {
    animation-delay: 0.1s;
}

@keyframes pulse {
    0% {
        transform: scale(0.8);
        background-color: #b3d4fc;
        box-shadow: 0 0 0 0 rgba(178, 212, 252, 0.7);
    }

    50% {
        transform: scale(1.2);
        background-color: #6793fb;
        box-shadow: 0 0 0 10px rgba(178, 212, 252, 0);
    }

    100% {
        transform: scale(0.8);
        background-color: #b3d4fc;
        box-shadow: 0 0 0 0 rgba(178, 212, 252, 0.7);
    }
}
</style>
